#!/usr/bin/env bash

# NodeOS
#
# Copyright (c) 2013-2017 Jacob Groundwater, Jesús Leganés-Combarro 'piranna'
# and other contributors
#
# MIT License

set -o pipefail


while getopts ":k:p:" opt; do
  case $opt in
    k)
      KERNEL="$OPTARG"  # linux, netbsd, nokernel
    ;;

    p)
      PLATFORM="$OPTARG"  # lxc, qemu, wsl
    ;;
  esac
done


# Default kernel and platform
if [[ -z "$KERNEL" ]]; then
  KERNEL=linux
fi

if [[ -z "$PLATFORM" ]]; then
  PLATFORM=qemu
fi


TOOLCHAIN=`node -p "require('nodeos-cross-toolchain')"`
BAREBONES=`node -p "require('nodeos-barebones')"`
INITRAMFS=`node -p "require('nodeos-initramfs')"`
USERSFS=`  node -p "require('nodeos-usersfs')"`

source $TOOLCHAIN/scripts/adjustEnvVars.sh || exit $?


OUT_DIR=`pwd`/out/$CPU_FAMILY/$MACHINE/$PLATFORM

export MACHINE

if [[ "$PLATFORM" == "docker" ]]; then
  export KERNEL=nokernel
fi

# Default: multiple users system
export SINGLE_USER=${SINGLE_USER-"nodeos-boot-multiUser"}

NPMi="npm install --arch=$NODE_ARCH --production"


#
# Build each layer up
#

( cd $BAREBONES && $NPMi ) &&
( cd $INITRAMFS && $NPMi ) || exit 10

if [ "$SINGLE_USER" == "nodeos-boot-multiUser" ]; then
  ( cd $USERSFS && $NPMi ) || exit 11
fi


#
# Wrap the system up and pack it
#

BAREBONES=$BAREBONES/out/$CPU
INITRAMFS=$INITRAMFS/out/${CPU}_${SINGLE_USER}
USERSFS=$USERSFS/out/$CPU.tar.gz

STEP_DIR=$OUT_DIR

mkdir -p $STEP_DIR

function copyAndConvertInitrams() {
  cpio2tar $BAREBONES/barebones.cpio.gz | gzip -c > $STEP_DIR/barebones              || err 20
  cpio2tar $INITRAMFS                   | gzip -c > $STEP_DIR/initramfs-$SINGLE_USER || err 21
}

case $MACHINE in
  pc)
    case $PLATFORM in
      disk)
        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 30

        nodeos-bootfs                \
            -F $PLATFORM             \
            -K $BAREBONES/bzImage    \
            -I $INITRAMFS            \
            -O $STEP_DIR/disk.img    \
            -U $STEP_DIR/usersfs.img || err 31

        rm -f $STEP_DIR/usersfs.img || err 32
      ;;

      docker)
        copyAndConvertInitrams || exit $?

        # Docker already provides `/dev/console` by default
        gunzip $STEP_DIR/barebones -c         | \
            tar --delete dev/console          | \
            gzip > $STEP_DIR/barebones.tar.gz || err 40

        mv $STEP_DIR/initramfs-$SINGLE_USER $STEP_DIR/initramfs.tar.gz || err 41

        # Exec `logon` directly instead of use `node-bin-getty` on the console
        mkdir -p root/etc && cp resources/palmtree.json root/etc || err 42

        gunzip $USERSFS -c                                              | \
            tar --delete root/etc/palmtree.json > $STEP_DIR/usersfs.tar || err 43

        tar -f $STEP_DIR/usersfs.tar -r root/etc/palmtree.json || err 44
        gzip -f $STEP_DIR/usersfs.tar                          || err 45

        # Delete temporal initrams
        rm -rf root $STEP_DIR/barebones $STEP_DIR/usersfs.tar || err 46
      ;;

      img)
        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 50

        nodeos-bootfs                \
            -F $PLATFORM             \
            -K $BAREBONES/bzImage    \
            -I $INITRAMFS            \
            -O $STEP_DIR/bootfs.img  \
            -U $STEP_DIR/usersfs.img || err 51
      ;;

      iso)
        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 60

        nodeos-bootfs                \
            -F $PLATFORM             \
            -K $BAREBONES/bzImage    \
            -I $INITRAMFS            \
            -O $STEP_DIR/bootfs.iso  \
            -U $STEP_DIR/usersfs.img || err 61
      ;;

      qemu)
        cp $BAREBONES/bzImage $STEP_DIR/kernel            || err 70
        cp $INITRAMFS         $STEP_DIR/initramfs.cpio.gz || err 71

        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 72
      ;;

      tar)
        copyAndConvertInitrams || exit $?

        nodeos-bootfs                           \
            -B $STEP_DIR/barebones              \
            -F $PLATFORM                        \
            -I $STEP_DIR/initramfs-$SINGLE_USER \
            -O $STEP_DIR/bootfs.tar.gz          || err 80

        cp $USERSFS $STEP_DIR/usersfs.tar.gz || err 81

        # Delete temporal initrams
        rm -f $STEP_DIR/barebones $STEP_DIR/initramfs-$SINGLE_USER || err 82
      ;;

      vagga)
        copyAndConvertInitrams || exit $?

        gunzip $STEP_DIR/barebones -c          | \
            tar --delete dev/console sbin/init | \
            gzip > $STEP_DIR/barebones.tar.gz  || err 90

        mv $STEP_DIR/initramfs-$SINGLE_USER $STEP_DIR/initramfs.tar.gz || err 91

        cp $USERSFS $STEP_DIR/usersfs.tar.gz || err 92

        # Delete temporal initrams
        rm -f $STEP_DIR/barebones || err 93
      ;;

      *)
        echo -e "${RED}Unknown platform '$PLATFORM'${CLR}"
        err 100
      ;;
    esac
  ;;

  raspi|raspi2|raspi3)
    case $PLATFORM in
      disk)
        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 110

        nodeos-bootfs                \
            -D $BAREBONES/dts        \
            -F $PLATFORM             \
            -K $BAREBONES/zImage     \
            -I $INITRAMFS            \
            -O $STEP_DIR/disk.img    \
            -U $STEP_DIR/usersfs.img || err 111

        rm -f $STEP_DIR/usersfs.img || err 112
      ;;

      img)
        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 120

        nodeos-bootfs                \
            -D $BAREBONES/dts        \
            -F $PLATFORM             \
            -K $BAREBONES/zImage     \
            -I $INITRAMFS            \
            -O $STEP_DIR/bootfs.img  \
            -U $STEP_DIR/usersfs.img || err 121
      ;;

      qemu)
        cp $BAREBONES/zImage $STEP_DIR/kernel || err 130

        mkdir -p $STEP_DIR/dts               &&
        cp -r $BAREBONES/dts/* $STEP_DIR/dts || err 131

        cp $INITRAMFS $STEP_DIR/initramfs.cpio.gz || err 132

        tar2ext $USERSFS nodeos 1 1 $STEP_DIR/usersfs.img || err 133
      ;;

      *)
        echo -e "${RED}Unknown platform '$PLATFORM'${CLR}"
        err 140
      ;;
    esac
  ;;

  *)
    echo -e "${RED}Unknown machine '$MACHINE'${CLR}"
    exit 150
  ;;
esac

ln -sfn $CPU_FAMILY/$MACHINE/$PLATFORM out/latest
